from .common import *

class ViewGeneratorPage4(wx.adv.WizardPage):
    '''个性化创建视图【第四页】'''
    def __init__(self, parent, title='第四步：设计当前节点路由路径', out_data = None):
        WizardPageSimple.__init__(self, parent)
        self.next = self.prev = None
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(self.sizer)
        if out_data is not None:
            self.out_data = out_data
            if VIEWS_WIZARD_CONTEXT not in self.out_data:
                self.out_data[VIEWS_WIZARD_CONTEXT] = {}
            self.context = self.out_data[VIEWS_WIZARD_CONTEXT]
            self.context['4'] = {}
            self.context = self.context['4']
        else:
            raise Exception('没有上下文，无法开启向导页面')

        self.group_ctrls = []
        self._init_UI(title)
        self._init_listener()

    def _init_UI(self, title):
        '''初始化界面布局'''
        '''
            设置当前页标题
        '''
        title = wx.StaticText(self, -1, title)
        title.SetFont(wx.Font(16, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
        self.sizer.Add(title, 0, wx.ALIGN_LEFT|wx.ALL, 3)
        self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 5) # 水平分割线

        '''
            所有的其他控件全部放在滚动面板中
        '''
        self.scollPanel = scrolledpanel.ScrolledPanel(self, -1, size=SIZE) # 定义滚动面板
        self.scollPanel.SetupScrolling() # 开启滚动
        self.scollPanelSizer = wx.BoxSizer(wx.VERTICAL)
        self.scollPanel.SetSizer(self.scollPanelSizer)
        self.sizer.Add(self.scollPanel, 1, wx.EXPAND | wx.ALL, 2) # 加入主容器

        self._init_scollpanel()

    def _init_scollpanel(self):
        '''初始化滚动窗口'''
        '''
            网格适应性布局
        '''
        self.flexGridSizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=2)
        self.scollPanelSizer.Add(self.flexGridSizer, 0, wx.EXPAND | wx.ALL, 5)
        self.flexGridSizer.AddGrowableCol(1) 

        # 控件
        self.inputUrlPath = wx.TextCtrl(self.scollPanel, -1, value='')
        self.inputUrlPathArgs = wx.TextCtrl(self.scollPanel, -1, value='')

        self.flexGridSizer.Add(wx.StaticText(self.scollPanel, -1, '设置路由路径'), 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.flexGridSizer.Add(self.inputUrlPath, 0, wx.EXPAND)
        self.flexGridSizer.Add(wx.StaticText(self.scollPanel, -1, '选填'), 0, wx.EXPAND)

        self.flexGridSizer.Add(wx.StaticText(self.scollPanel, -1, '路径携带字典'), 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.flexGridSizer.Add(self.inputUrlPathArgs, 0, wx.EXPAND)
        self.flexGridSizer.Add(wx.StaticText(self.scollPanel, -1, '选填'), 0, wx.EXPAND)

        '''
            路由参数设置
        '''
        self.staticBoxAll = wx.StaticBox(self.scollPanel, -1, '路由参数设置')
        self.staticBoxAllSizer = wx.StaticBoxSizer(self.staticBoxAll, wx.VERTICAL)
        self.scollPanelSizer.Add(self.staticBoxAllSizer, 0, wx.EXPAND | wx.ALL, 3)
        self.staticBoxAll.SetForegroundColour(wx.BLUE)

        '''
            系统路径转换器
        '''
        self._init_sys_path_convert()
            
        '''
            自定义路径转换器
        '''
        self._init_custom_path_convert()
    
    def _init_sys_path_convert(self):
        """系统路径转换器"""
        self.staticBoxSysConvert = wx.StaticBox(self.scollPanel, -1, '系统路径转换器')
        self.staticBoxSysConvertSizer = wx.StaticBoxSizer(self.staticBoxSysConvert, wx.VERTICAL)
        self.staticBoxSysConvert.SetForegroundColour('#a52a2a')
        self.staticBoxAllSizer.Add(self.staticBoxSysConvertSizer, 0, wx.EXPAND | wx.ALL, 3)

        self.flexGridSizerSys = wx.FlexGridSizer(cols=3, hgap=5, vgap=3)
        self.staticBoxSysConvertSizer.Add(self.flexGridSizerSys, 0, wx.EXPAND|wx.ALL, 1)
        self.flexGridSizerSys.AddGrowableCol(1)

        radio1 = wx.RadioButton(self.scollPanel, -1, "str", style = wx.RB_GROUP)
        radio2 = wx.RadioButton(self.scollPanel, -1, "int")
        radio3 = wx.RadioButton(self.scollPanel, -1, "slug")
        radio4 = wx.RadioButton(self.scollPanel, -1, "uuid")
        radio5 = wx.RadioButton(self.scollPanel, -1, "path")

        text1 = wx.TextCtrl(self.scollPanel, -1, "")
        text2 = wx.TextCtrl(self.scollPanel, -1, "")
        text3 = wx.TextCtrl(self.scollPanel, -1, "")
        text4 = wx.TextCtrl(self.scollPanel, -1, "")
        text5 = wx.TextCtrl(self.scollPanel, -1, "")

        tip1 = wx.StaticText(self.scollPanel, -1, "str@匹配除'/'外的非空字符串(默认)")
        tip2 = wx.StaticText(self.scollPanel, -1, "int@匹配非负整数")
        tip3 = wx.StaticText(self.scollPanel, -1, "slug@匹配ASCII字母、数字、连字符、下划线")
        tip4 = wx.StaticText(self.scollPanel, -1, "uuid@匹配一个格式化的UUID")
        tip5 = wx.StaticText(self.scollPanel, -1, "path@匹配非空字符串，包括'/'")

        self.btnAdd = buttons.GenButton(self.scollPanel, -1, "添加路径参数")
        self.btnAdd.SetBackgroundColour(CON_COLOR_MAIN)
        self.btnAdd.SetForegroundColour(CON_COLOR_PURE_WHITE)

        self.group_ctrls.append((radio1, text1, tip1))
        self.group_ctrls.append((radio2, text2, tip2))
        self.group_ctrls.append((radio3, text3, tip3))
        self.group_ctrls.append((radio4, text4, tip4))
        self.group_ctrls.append((radio5, text5, tip5))

        for radio, text, tip in self.group_ctrls:
            self.flexGridSizerSys.Add(radio, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL, 5)
            self.flexGridSizerSys.Add(text, 0, wx.EXPAND, 5)
            self.flexGridSizerSys.Add(tip, 0, wx.ALIGN_LEFT|wx.EXPAND, 5)
        
        self.flexGridSizerSys.Add((5,5), 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL, 5)
        self.flexGridSizerSys.Add(self.btnAdd, 0, wx.EXPAND, 5)
        self.flexGridSizerSys.Add((5,5), 0, wx.ALIGN_LEFT|wx.EXPAND, 5)

        for radio, text, tip in self.group_ctrls:
            radio.SetValue(0)
            text.Enable(False)

    def _init_custom_path_convert(self):
        """自定义路径转换器"""
        self.staticBoxCustomConvert = wx.StaticBox(self.scollPanel, -1, '自定义路径转换器')
        self.staticBoxCustomConvertSizer = wx.StaticBoxSizer(self.staticBoxCustomConvert, wx.VERTICAL)
        self.staticBoxCustomConvert.SetForegroundColour('#a52a2a')
        self.staticBoxAllSizer.Add(self.staticBoxCustomConvertSizer, 0, wx.EXPAND | wx.ALL, 3)

        self.staticBoxCustomConvertSizer.Add(wx.StaticText(self.scollPanel, -1, "功能构思中......"), 0, wx.EXPAND|wx.ALL, 1)

    def _init_listener(self):
        """注册监听"""
        '''
            向导页面事件监听
        '''
        self.Bind(wx.adv.EVT_WIZARD_PAGE_CHANGING, self.onWizPageChanging)
        self.Bind(wx.adv.EVT_WIZARD_CANCEL, self.onWizCancel)

        for radio, text, tip in self.group_ctrls:
            self.Bind(wx.EVT_RADIOBUTTON, self.onGroupSelect, radio )

        self.Bind(wx.EVT_BUTTON, self.onBtnAdd, self.btnAdd)

    def onBtnAdd(self, evt):
        """添加路径参数"""
        for radio, text, tip in self.group_ctrls:
            if radio.GetValue():
                # 获取当前已经填写的路由
                temp_v = self.inputUrlPath.GetValue().strip(string.whitespace + '/')
                temp_add_v = text.GetValue().strip(string.whitespace + '/')
                temp_tip = tip.GetLabelText().split('@')[0]
                if not temp_add_v:
                    RichMsgDialog.showOkMsgDialog(self, f"选中的{temp_tip}类型的参数未命名", "警告")
                    return
                temp_add_v = f"<{temp_tip}:{temp_add_v}>"
                self.inputUrlPath.SetValue(temp_v + ('/' if temp_v else '') + temp_add_v + '/')
                text.SetValue('')
                break

    def onGroupSelect(self, evt):
        """"""
        radio_selected = evt.GetEventObject()
        for radio, text, tip in self.group_ctrls:
            text.SetValue('')
            if radio is radio_selected:
                text.Enable(True)
            else:
                text.Enable(False)

    def onWizCancel(self, evt):
        """界面取消时触发"""
        if not RichMsgDialog.showYesNoMsgDialog(self, '【取消】/【关闭】将导致已填的数据全部被丢弃！', "警告"):
            evt.Veto()

    def onWizPageChanging(self, evt):
        """向导页切换时触发"""
        self.context['url'] = self.inputUrlPath.GetValue().strip(string.whitespace+'/') + '/'
        if '/' == self.context['url']:
            self.context['url'] = ''
        self.context['args'] = self.inputUrlPathArgs.GetValue().strip()

    def SetNext(self, next):
        '''设置后一页'''
        self.next = next

    def SetPrev(self, prev):
        '''设置前一页'''
        self.prev = prev

    def GetNext(self):
        '''获取下一页/下一指定页'''
        return self.next

    def GetPrev(self):
        '''获取上一页/上一指定页'''
        return self.prev
